package com.qianya.oa.listener;

import com.qianya.oa.annotation.CustomTaskListener;
import com.qianya.oa.common.core.domain.entity.SysUser;
import com.qianya.oa.service.SysUserMessageService;
import com.qianya.oa.service.SysUserService;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service("taskNotifyListener")
@CustomTaskListener("流程提醒推送")
public class TaskNotifyListener implements TaskListener {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private SysUserMessageService sysUserMessageService;

    @Resource
    private RepositoryService repositoryService;

    private static final String SEPARATOR = " ";

    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("执行任务监听器");
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(delegateTask.getProcessInstanceId()).singleResult();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId());
        Process process = bpmnModel.getProcesses().get(0);
        if (processInstance == null) {
            UserTask nextUserTask = getNextUserTaskAssign(process, delegateTask.getTaskDefinitionKey());
            // 发送提醒消息
            if (nextUserTask != null) {
                String message = "你发起了新流程：" + SEPARATOR + process.getName();
                message = message + SEPARATOR + "下一个任务：" + SEPARATOR + nextUserTask.getName();
                SysUser targetSysUser = sysUserService.selectUserByLoginName(delegateTask.getAssignee());
                sysUserMessageService.sendAndSaveMessage(targetSysUser.getUserId(), targetSysUser.getUserName(),
                        1, "系统消息", message);
            }
        } else {
            // 发送提醒消息
            SysUser startSysUser = sysUserService.selectUserByLoginName(processInstance.getStartUserId());
            SysUser targetSysUser = sysUserService.selectUserByLoginName(delegateTask.getAssignee());
            String message = startSysUser.getUserName() + SEPARATOR + "发起了流程：" + SEPARATOR + process.getName();
            message = message + SEPARATOR + "当前任务：" + SEPARATOR + delegateTask.getName()
                    + SEPARATOR + "处理人：" + SEPARATOR + targetSysUser.getUserName();
            sysUserMessageService.sendAndSaveMessage(targetSysUser.getUserId(), targetSysUser.getUserName(),
                    2, "系统消息", message);
        }
    }

    public UserTask getNextUserTaskAssign(Process process, String currentFlowElementId) {
        //获取所有普通任务节点
        List<UserTask> userTaskList = process.findFlowElementsOfType(UserTask.class);
        for (UserTask userTask : userTaskList) {
            //获取当前任务节点Id
            String id = userTask.getId();
            if (id.equals(currentFlowElementId)) {
                //获取当前任务节点的所有出线信息
                List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
                for (SequenceFlow sequenceFlow : outgoingFlows) {
                    //获取出线连接的目标节点
                    FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
                    //获取到了下一个节点的Id
                    String nextId = targetFlowElement.getId();
                    List<UserTask> userTaskLists = process.findFlowElementsOfType(UserTask.class);
                    //再次遍历所有普通任务节点
                    for (UserTask userTasks : userTaskLists) {
                        //获取任务节点Id
                        String flowId = userTasks.getId();
                        //如果遍历的某个任务节点Id等于下一个节点的Id
                        if (flowId.equals(nextId)) {
                            //获取下一个任务节点的执行人
                            return userTasks;
                        }
                    }
                }
            }
        }
        return null;
    }
}
